<!-- 依赖图 -->
<!-- http://www.echartsjs.com/option.html#series-graph -->

<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.staticfile.org/jquery/1.12.4/jquery.min.js"></script>
<script src="//cdn.staticfile.org/echarts/5.2.1/echarts.min.js"></script>
<script type="text/javascript">
    $(function() {
        var winH = $(window).height();
        $("#echarts-2").css('height', (winH - 16) + 'px'); 

        // 依赖关系转饼图
        var symbolSector = function (_x, _y) {
            if( _x < 1 && _y < 1 ) {
                return 'circle';
            }

            var _radius = 35; // 半径

            var canvas = document.createElement('canvas');
            canvas.width = _radius * 2;
            canvas.height = _radius * 2;
            document.body.appendChild(canvas);
            var context = canvas.getContext('2d');

            var _sector = function(context, x, y, r, a, b) {
                context.save();
                context.beginPath();
                context.moveTo(x,y);
                context.arc(x, y, r, a, b);
                context.closePath();    
                context.restore();
                return context;
            }

            var _z = ( _y / ( _x + _y ) ) * 2 * Math.PI;

            context.fillStyle = 'red';
            _sector( context, _radius, _radius, _radius, 0 * Math.PI, _z ).fill();
            context.fillStyle = 'blue';
            _sector( context, _radius, _radius, _radius, _z, 2 * Math.PI ).fill();

            var dataURL = canvas.toDataURL('image/png');

            document.body.removeChild(canvas);

            return 'image://' + dataURL;
        };

        // echarts 配置对象
        var _series = {
            type : 'graph',
            layout : 'force',
            roam : true, // 开启鼠标缩放和平移漫游
            focusNodeAdjacency : true, // 鼠标移到节点上的时候突出显示
            draggable : true, // 可拖动
            symbolSize : 25, // 图标大小
            edgeSymbol : [ 'none', 'arrow' ],
            force : {
                initLayout : 'circular', 
                repulsion : [300, 600], // 斥力因子
                gravity : 0.1, // 引力因子
                edgeLength : [100, 500] // 距离范围
            },
            label : {
                show : true // 显示名称
            },
            lineStyle : { 
                width : 2 // 线条宽度
            },
            nodes : [],
            links : []
        }

        // 关系强度
        var _count_in_links = function ( _name, _links ) {
            var _x = 0;
            var _y = 0;

            _links.forEach(function(_each){
                if( _each.source == _name ) {
                    _x = _x +1;
                }
                if( _each.target == _name ) {
                    _y = _y +1;
                }
            });

            return [_x, _y];
        };

        // 鼠标指向时的漂浮提示
        var _tooltip = {
            enterable : true,
            formatter : function ( _a ) {
                if ( 'node' == _a.dataType ) { // 节点
                    var _count = _count_in_links( _a.data.name, _series.links );
                    return '项目 : ' + _a.data.name + '<br/>依赖的项目 : ' + _count[1] + '个<br/>依赖我的项目 : ' + _count[0] + '个';
                } else { // 连线
                    return '依赖关系 : ' + _a.name;
                }
            }
        };

        // init echarts
        var _echarts = echarts.init(document.getElementById('echarts-2'));

        // 绑定拖动事件
        _echarts.on('mouseup', 'series', function( _params ) {
            if ( _params.dataType == 'node' ) { // 节点拖动事件
                if ( 1 == _params.event.which ) { // 左键拖动
                    _series.nodes.forEach( function( _each ) {
                        if ( _params.data.name == _each.name ) { _each.fixed = true; } // 锁定位置
                    } ) ;
                    _echarts.setOption({ series : [ _series ] }); // 渲染
                } else if ( 3 == _params.event.which || 2 == _params.event.which ) { // 右键中键释放
                    _series.nodes.forEach( function( _each ) {
                        if ( _params.data.name == _each.name ) { _each.fixed = false; } // 不锁定位置
                    } ) ;
                    _echarts.setOption({ series : [ _series ] }); // 渲染
                }
            } 
        } );

        _echarts.showLoading();

        // load application
        $.ajax({
            url : "application.json",
            dataType : "json"
        }).then(function(responseJson) {
            var _nameMap = {};
            for (var i = 0; i < responseJson.length; i++) {
                var _name = responseJson[i].name;
                _nameMap[_name] = _name;
            }

            for (_key in _nameMap) {
                _series.nodes.push({ name : _key });
            }

            _echarts.hideLoading();
            _echarts.setOption({ title: { text: '项目依赖关系图' }, tooltip : _tooltip, series : [ _series ] }); // 渲染

            _echarts.showLoading();
            $.ajax({
                url : "application-force.json",
                dataType : "json"
            }).then(function(responseJson) {
                for (var i = 0; i < responseJson.length; i++) {
                    var _link = responseJson[i];
                   _series.links.push(_link);
                }

                // 图标大小
                _series.nodes.forEach(function(each) {
                    var _count = _count_in_links( each.name, _series.links );
                    each.symbolSize = 25 + _count[0] + _count[1];
                    each.symbol = symbolSector(_count[0], _count[1]);
                });

                _echarts.setOption({ series : [ _series ] }); // 渲染
                _echarts.hideLoading();
            });
        });
    });
</script>
</head>

<body>
    <div id="echarts-2" style="width: 100%;">
        <h1>loading ...</h1>
    </div>
</body>